

#include "includes.h"

struct memspace *
msp_init(unsigned int size)
{
  unsigned int total_size = size + sizeof(struct memspace);
  struct memspace *m = (struct memspace *) calloc(1, total_size);

  if (m == NULL)
    {
      printf("Couldn't initialize memory space of %d bytes\n", size);
      exit(1);
    }
  
  m->limit = ((void *) &m->data) + size;
  m->offset = &m->data;

  return m;
}

void *
msp_addr(struct memspace *mp)
{
  return mp->offset;
}

void *
msp_alloc(struct memspace **mp, unsigned int size)
{
  struct memspace *m = *mp;
  if (m->offset + size < m->limit)
    {
      void *o = m->offset;
      m->offset += size;
      return o;
    }

  unsigned int new_size = (m->limit - (void *) m) * 2 + size; 
  void *old = m;
  m = realloc((void *) m, new_size);
  int diff = (unsigned int) m - (unsigned int) old;
  printf("Realloc %d bytes:  0x%x diff: %d\n", new_size, (int) m, diff);
  
  if (!m)
    {
      return 0x0;
    }
  
  m->offset += diff;
  void *o = m->offset;
  m->offset += size;
  m->limit = ((void *) m) + new_size;
  *mp = m;
  return o;
}


int
msp_check(struct memspace *mp, unsigned int size)
{
  if (mp->offset + size < mp->limit) return MSP_SAFE;

  return MSP_NEEDS_RESIZE;
}

